using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using dnAnalytics.Math;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.LinearAlgebra.Decomposition;
using dnAnalytics.LinearAlgebra.IO;
using dnAnalytics.Exceptions;

namespace dnAnalytics.UnitTests.LinearAlgebra.Decomposition
{
    public class DenseCholeskyTest : AbstractCholeskyTest
    {
        public override Matrix GetMatrix(int rows, int columns)
        {
            return MatrixBuilder.CreateMatrix(rows, columns, MatrixType.Dense);
        }

        public override Matrix GetMatrix(int order)
        {
            return MatrixBuilder.CreateMatrix(order, MatrixType.Dense);
        }

        public override void GetDecompositionClass(String file, out Matrix matrix, out Cholesky cholesky)
        {
            MatrixMarketReader mmr = new MatrixMarketReader();
            matrix = mmr.ReadMatrix(file, MatrixType.Dense);
            cholesky = new Cholesky(matrix);
        }

        public override Vector GetVector(int size)
        {
            return VectorBuilder.CreateVector(size, VectorType.Dense);
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Dense")]
    public class ManagedDenseCholeskyTest : DenseCholeskyTest
    {
        static ManagedDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Dense")]
    public class MklDenseCholeskyTest : DenseCholeskyTest
    {
        static MklDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Dense")]
    public class AcmlDenseCholeskyTest : DenseCholeskyTest
    {
        static AcmlDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Dense")]
    public class AtlasClapackDenseCholeskyTest : DenseCholeskyTest
    {
        static AtlasClapackDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Managed")]
    [Category("Dense")]
    public class ManagedSparseDenseCholeskyTest : DenseCholeskyTest
    {
        static ManagedSparseDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = false;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Mkl")]
    [Category("Dense")]
    public class MklSparseDenseCholeskyTest : DenseCholeskyTest
    {
        static MklSparseDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Mkl;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Mkl;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Acml")]
    [Category("Dense")]
    public class AcmlSparseDenseCholeskyTest : DenseCholeskyTest
    {
        static AcmlSparseDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Acml;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("Atlas")]
    [Category("Dense")]
    public class AtlasClapackSparseDenseCholeskyTest : DenseCholeskyTest
    {
        static AtlasClapackSparseDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Atlas;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.Clapack;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortDenseCholeskyTest : DenseMatrixTest
    {
        static AcmlIFortDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Dense;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Dense;
        }
    }

    [TestFixture]
    [Category("Native")]
    [Category("AcmlIFort")]
    [Category("Dense")]
    public class AcmlIFortSparseDenseCholeskyTest : DenseMatrixTest
    {
        static AcmlIFortSparseDenseCholeskyTest()
        {
            dnAnalytics.Settings.UseNativeLibrary = true;
            dnAnalytics.Settings.Blas = dnAnalytics.LinearAlgebra.Native.BlasProvider.Acml;
            dnAnalytics.Settings.Lapack = dnAnalytics.LinearAlgebra.Native.LapackProvider.AcmlIFort;
            dnAnalytics.Settings.DefaultMatrixType = MatrixType.Sparse;
            dnAnalytics.Settings.DefaultVectorType = VectorType.Sparse;
        }
    }
}
